<template>
  <div class="container">
    <div @mouseup.stop="mouseup($event)" ref="article" class="article">
      <p>洒满星星的河流</p>

　　  <p>我已经远离了你的河流，绝不是疏远，因为我已是身居异土。远远地，依然听得到你翻山越岭、日夜兼程的脚步声，依然无比清晰地看得到你的那条洒满星星的清澈的河流。只要，也只有想起你——故乡，就是异域的那条河流也会洒满故乡的星星。无论醒着还是沉睡，都会重复着那个让人心旌摇曳的画面，星星都在你的河流里百媚地眨眼。因为那条洒满星星的河流途经我无猜的孩童，无知的少年，迷茫的青春，还要经过可知的未来，是不是今后还要交付给大海了呢？那样，大海的那些星星一定是故乡送给他们的馈赠，没有故乡的孕育，大海也会失去灵气，因为大海的源头就在故乡的这头……</p>

　　  <p>星星的感情，在城市里总是被耽误。是星星的感情单一，还是城市的滥情呢？如果城市是舞台，星星就不是市民，所以也不是演员。如果天空是舞台，星星就是居民，所以能成为明星。如果河流是舞台，星星就是精灵，她就是大地的灵魂。如今，爱情在城市里就是一个错误，比金钱的质量轻百倍，所以比海洛因更危险。爱情在乡村的河流里，就有了星星的光辉，成就的是海枯石烂的传奇……</p>
    
      <p>晴空万里的白昼，总爱涂脂抹粉打扮一番。这样的时候，只有清泉敢从浓妆艳抹的云端踏过，只有披着满身星星的鱼儿敢从蓝天穿过，将自满表现的太阳戏弄一番。浆洗的女人们总爱把笑声抛在河面上，拍打着棒槌当爵士乐的节拍，委婉的歌声随着幸福的河水流淌，斑斓的衣服在白云间飘舞成了彩虹。我听到了大地与天空的窃语，彻底悟出了萨顶顶唱的《万物生》里的深刻与凝重：我看见山鹰在寂寞两条鱼上飞 ，两条鱼儿穿过海一样咸的河水， 一片河水落下来遇见人们破碎 ，人们在行走，身上落满山鹰的灰……</p>

　　  <p>睡得沉沉的夜，呵欠连连，漫长得没有尽头，无论夜几多的黑，可故乡的河流从也不会迷路，因为有星星这明亮的眼睛。你的人生没有迷路，你的梦没有迷失方向，你的未来总在奔跑的路上，是不是也是借了故乡河流里的星星做慧眼呢？如果河流看不到星星，那肯定会落魄的。如果人生看不到那条飘着星星的河流，如果梦里没有那条飘着星星的河流，如果未来的路上没有那条飘着星星的河流，你是不是都会惊慌失措呢？陌生人能通过那条河流找到你的家，如果没有了她你的心能到家吗？</p>

　　  <p>故乡那条洒满星星的河流，已经成了一幕刻骨铭心的风景了，我知道能刻骨铭心的是最致命的东西，我是一个能被往事打动的人，我还敢不把她珍藏在比记忆还要深刻的心头吗？如果哪天放手丢失了，我的儿子、孙子会替我捡起永远珍藏下去的。</p>

　　  <p>我翻阅过世界地图，也翻阅过中国地图，让我大失所望的是没能找到故乡那条洒满星星的河流。他只是奔流着的一根毛细血管，往往被大意的世人疏忽。打开谷歌地图，还是难以描绘出她窈窕的身姿。看到两旁葱葱郁郁的树，飘飘舞舞的路，歪歪斜斜的村落……才恍然大悟这是滋生生命的源头</p>！

　　  <p>那条河流，滋生过五谷杂粮，抚慰过萝卜白菜，滋养过冒冒失失的人们……我是数着河里的星星，翻开人生的第一页，演算过老师递过来的复杂的难题，懂得了几个因为，见识了几个所以。再后来那条河流一直陪着我，从故乡走到异乡……</p>

　　  <p>心中有了那条洒满星星的河流，心灵就不会陷入绝境。让我把她和与她的过往都珍藏起来了，交付给未来吧。</p>

      <p>在故乡重重叠叠的夜色里自己轻而易举就跌进了回忆里，一道弯也没有拐就触摸到了往日的美好。你是不是在猜想，此刻我端着一杯闲茶，或是端着一杯闷酒，要么抽着一根无聊的烟呢？因为它们是回忆的发起人呀？但是，你是否知道闲茶、闷酒、无聊烟也是记忆的掘墓人呢？要么是晴天里，纵横流淌的意识又发挥了最大长处，把积攒多日的感情得以充分的表达？你想错了，彻底错了，因为是那圣洁的月光，全美了我温暖的过往。故乡的月亮才是那只发现的眼儿，她发现了淡淡的乡愁，但是发现更多的还是往昔擦肩而过的美好……</p>

　　  <p>今生总是喜欢站在故乡的月光下重复听着一首歌：“妈妈，月光之下，静静地　　我想你了，静静淌在血里的牵挂……妈妈　　月亮之下，有了你　　我才有家，离别虽半步即是天涯……”歌声俘获了游子疲惫会痛的灵魂，月光抚摸了游子尖锐疼痛的忧伤……</p>
    
      <p>不是笑话，也算不上美谈，今生在我没有来得及恋爱的年纪就已经恋爱了，我的恋爱史比我的年纪还大，大得不多仅仅一个春秋。湖北黄石市你知道不？不出名是吧？也难怪，它很年轻，和新中国一样大。在那座年轻的城市里，在那个天下饥荒未断的一九六三年，两对年轻的夫妇为了糊口相聚在青山湖边，投入了这座年轻的城市的基础建设，他们都来自矿冶名城——大冶，但是不是一个公社。他们相互照顾，情同手足。一个风雨交加的夜里，他们暂住的工棚突然坍塌，这两对夫妇劫后幸存。在雨停后的第一个疲惫的夜晚，他们当着朗朗皓月指腹为盟：如果都是男孩就是兄弟，如果是女孩就是姐妹，如果是男女各一将来就是对夫妻……一年后，上苍如此安排，我就是那个男孩，她就是那个女孩……二十三年后，幸福如此安排，我就成了那个丈夫，她就成了那个妻子……</p>

　　  <p>不算浪漫，却有着一点点忧伤。在我迷迷茫茫到处撒下青春种子的年纪，却发生了一段让我我刻骨铭心的遇见。那年我刚刚步入十七，是最喜欢做梦的年纪。那是一个晴朗的星期一大清早，我挎着绿色军包去学校报到。悠闲地走进民主街，一盆洗脸水从天而降，虽没有落个正着也湿了半条裤腿。一个男孩当然不会用恶毒的方言骂街，但是不开口就白白蒙冤，正待发作窗口探出一张美丽的笑脸：对不起，我不懂事的妹妹太鲁莽，要骂你就骂几句解解气吧……如果再骂，我是不是太不高尚了，我无奈笑了笑：没事，没事……</p>
    
    </div>
    <a-table
      class="table"
      :columns="columns"
      :data-source="tableData"
      bordered 
      :pagination="false"
      rowKey="markId"
      size="middle"
      >
      <div slot="index" slot-scope="text, record, index">
        {{ index + 1 }}
      </div>
      <div slot="markId" slot-scope="text, record, index">
        <a-button @click="location(record)" type="link">{{ '定位' + (index + 1) }}</a-button>
      </div>
      <div slot="operation" slot-scope="text, record">
        <a-button @click="deleteMark(record)" type="link" size="small">删除</a-button>
      </div>
    </a-table>
    <a-button
      v-if="isAddButton"
      class="add-button"
      ref="addButton"
      type="primary"
      @click="addButton"
    >添加标注</a-button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      columns: [
        { title: '序号', dataIndex: 'index', align: 'center', width: 70, scopedSlots: { customRender: 'index' } },
        { title: '定位', dataIndex: 'markId', align: 'center', width: 100, scopedSlots: { customRender: 'markId' } },
        { title: '内容', dataIndex: 'content', ellipsis: true },
        { title: '操作', dataIndex: 'operation', align: 'center', width: 100, scopedSlots: { customRender: 'operation' } }
      ],
      tableData: [],
      isAddButton: false
    };
  },
  created () {
    // 选中取消时, 隐藏按钮
    document.addEventListener('selectionchange', () => {
      if (this.isAddButton && !window.getSelection().toString()) {
        this.isAddButton = false
      }
    })
  },
  methods: {
    /** @name 鼠标抬起 **/
    mouseup (e) {
      // 未选中
      if (!window.getSelection().toString()) return

      // 插入交互
      this.insetAffix(e)
    },
    /** @name 插入标注交互 **/
    insetAffix (e) {
      this.isAddButton = true
      this.$nextTick(() => {
        const { clientX, clientY } = e
        const addButton = this.$refs.addButton.$el;
        const offset = 5
        addButton.style.cssText = `top: ${clientY + offset}px; left: ${clientX + offset}px; z-index: 10`
      })
    },
    /** @name 添加标注 **/
    addButton() {
      this.isAddButton = false

      const selectedContent = window.getSelection()

      // 创建新节点
      const mark = document.createElement('span')
      mark.className = 'yd-mark'
      const id = `yd-${new Date().getTime()}`
      mark.id = id

      // 将选中的内容移动到新节点
      const range = selectedContent.getRangeAt(0)
      try {
        range.surroundContents(mark)
      } catch (error) {
        this.$message.error('不能重复标记1')
        console.warn(error)
        window.getSelection().removeAllRanges()
        return
      }

      // 获取选中内容所属的节点
      const anchorNode = selectedContent.anchorNode
      const isRepeatMark = anchorNode.classList.contains('yd-mark')
      if (isRepeatMark) {
        this.$message.error('不能重复标记')
        window.getSelection().removeAllRanges()
        this.deleteMark(id)
        return
      }

      // 选中的内容
      const content = window.getSelection().toString()

      // 移除选中状态
      window.getSelection().removeAllRanges()

      this.tableData.push({
        markId: id,
        content
      })
    },
    /** @name 定位 **/
    location(record) {
      const content = this.$refs.article
      const targetNode = content.querySelector(`#${record.markId}`)
      targetNode.scrollIntoView({
        behavior: 'smooth',
        block: 'center'
      })
    },
    /** @name 删除标注 **/
    deleteMark(record) {
      const index = this.tableData.find(item => item.markId === record.markId)
      this.tableData.splice(index, 1)
      const content = this.$refs.article
      const targetNode = content.querySelector(`#${record.markId}`)
      const targetText = targetNode.firstChild.nodeValue
      const parentNode = targetNode.parentNode
      // 先插入新节点
      const textNode = document.createTextNode(targetText)
      parentNode.insertBefore(textNode, targetNode)
      // 再删除旧节点
      parentNode.removeChild(targetNode)
    }
  }
}
</script>

<style scoped>
.article {
  white-space: pre-wrap;
  width: 400px;
}
.container {
  display: flex;
}
.table {
  width: 600px;
}
.add-button {
  position: fixed;
  top: 0;
  left: 0;
  z-index: -1;
}
</style>

<style>
.yd-mark {
  background-color: #FFF8DB;
  padding: 0 0.2em;
  position: relative;
}
</style>